﻿using DataMgr.File;
using DataMgr.mode;
using DataMgr.msg;
using DataMgr.msg.req;
using OfficeOpenXml;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace DataMgr.Export
{
    enum ExportElment : int
    {
        Export_StepInfo = 0x01,
        Export_Log = 0x02,
        Export_CycleLayer = 0x04,
        Export_StepLayer = 0x08,
        Export_RecordLayer = 0x10,
        Export_Graph = 0x20,
    }
    class BdfExport
    {
        static object m_lockObj = new object();
        public static List<FileExportInfo> m_exportInfo = new List<FileExportInfo>();
        //private static Hashtable m_exportCancel = new Hashtable();  //<destFile,CancellationTokenSource>

        static FileExportInfo GetExportInfo(string destFile)
        {
            foreach (FileExportInfo item in m_exportInfo)
            {
                if (item.Request.destFile == destFile)
                    return item;
            }

            return null;
        }

        //接收导出请求
        public static int RecExportMsg(string reqMsg)
        {
            ReqBdfExport req = new ReqBdfExport();
            req.Parse(reqMsg);

            //string sKey = req.guidPath + req.chlId.ToString();
            lock (m_lockObj)
            {
                FileExportInfo exportInfo = GetExportInfo(req.destFile);
                if (null == exportInfo) //首次添加并启动任务
                {
                    FileInfo newFile = new FileInfo(req.srcFile);
                    if (!newFile.Exists)
                        return -1;  //源文件不存在 

                    exportInfo = new FileExportInfo();
                    exportInfo.Request = req;

                    m_exportInfo.Add(exportInfo);

                    //var cts = new CancellationTokenSource();
                    //m_exportCancel[req.destFile] = cts;
                    var longTask = new Task<int>(() => Export(req.destFile, exportInfo.cancelSource.Token),
                        exportInfo.cancelSource.Token);
                    longTask.Start();
                }
                else if (req.operFlag == 0) //取消导出请求
                {
                    exportInfo.cancelSource.Cancel();
                    //删除文件
                }
                else
                {
                    FileInfo newFile = new FileInfo(exportInfo.Request.destFile);
                    if (!newFile.Exists)
                    {
                        m_exportInfo.Remove(exportInfo);    //重新下载
                        exportInfo = new FileExportInfo();
                        exportInfo.Request = req;

                        m_exportInfo.Add(exportInfo);
                        var longTask = new Task<int>(() => Export(req.destFile, exportInfo.cancelSource.Token),
                            exportInfo.cancelSource.Token);
                        longTask.Start();

                    }
                    else
                        return -1;
                }
            }

            return 0;
        }

        public static RspExportProgress QueryExportMsg(string reqMsg)
        {
            ReqExportProgress req = new ReqExportProgress();
            req.Parse(reqMsg);
            RspExportProgress rsp = new RspExportProgress();
            FileExportInfo exportInfo = GetExportInfo(req.destFile);
            if (null != exportInfo)
            {
                if (exportInfo.finishRows < exportInfo.totalRows)
                {
                    TimeSpan spead = DateTime.Now.Subtract(exportInfo.BeginTime);
                    rsp.time = spead.TotalMilliseconds;
                }
                else
                {
                    TimeSpan spead = exportInfo.EndTime.Subtract(exportInfo.BeginTime);
                    rsp.time = spead.TotalMilliseconds;
                }
                rsp.total = exportInfo.totalRows;
                rsp.finish = exportInfo.finishRows;
                rsp.destFile = req.destFile;
            }

            return rsp;
        }

        //线程中执行导出
        private static int Export(string destFile, CancellationToken token)
        {
            FileExportInfo exportInfo = GetExportInfo(destFile);
            exportInfo.BeginTime = DateTime.Now;
            BdfAdapter adapter = new BdfAdapter();
            if (!adapter.Open(exportInfo.Request.srcFile, (CycleDivideKind)exportInfo.Request.cycleType,
                (ushort)exportInfo.Request.startStep, (ushort)exportInfo.Request.stepCount))
            {
                MsgUtil.WriteLog(string.Format("文件无法打开{0}，导出失败", exportInfo.Request.srcFile));
                return -1;
            }

            CalcProgressInfo(ref exportInfo, adapter);
            FileInfo newFile = new FileInfo(exportInfo.Request.destFile);
            if (newFile.Exists)
            {
                try
                {
                    newFile.Delete();
                }
                catch (Exception e)
                {
                    MsgUtil.WriteLog(string.Format("可能用户打开文件，目标文件无法删除{0}，导出失败{1}", exportInfo.Request.destFile, e.Message));
                    return -1;
                }
                Thread.Sleep(50);
                newFile = new FileInfo(exportInfo.Request.destFile);
                if (newFile.Exists)
                {
                    MsgUtil.WriteLog(string.Format("文件无法删除{0}，导出失败", exportInfo.Request.destFile));
                    return -1;
                }

                newFile = new FileInfo(exportInfo.Request.destFile);
            }

            using (ExcelPackage package = new ExcelPackage(newFile))
            {
                if (exportInfo.Request.exportType == 1)
                {
                    if ((exportInfo.Request.exportOption & (int)ExportElment.Export_CycleLayer) > 0)
                        WriteLayerCyclePage(package, adapter, ref exportInfo);

                    if ((exportInfo.Request.exportOption & (int)ExportElment.Export_StepLayer) > 0)
                    {
                        if (token.IsCancellationRequested)
                            return -1;
                        else
                            WriteLayerStepPage(package, adapter, ref exportInfo);
                    }
                    if ((exportInfo.Request.exportOption & (int)ExportElment.Export_RecordLayer) > 0)
                        if (-1 == WriteLayerRecordPage(package, adapter, ref exportInfo, token))
                            return -1;
                }
                else if (exportInfo.Request.exportType == 2)
                {
                    WriteNoramlPage(package, adapter, ref exportInfo, token);
                }

                if ((exportInfo.Request.exportOption & (int)ExportElment.Export_Log) > 0)
                {
                    if (token.IsCancellationRequested)
                        return -1;
                    else
                        exportInfo.finishRows += WriteLogPage(package, adapter);
                }
                if ((exportInfo.Request.exportOption & (int)ExportElment.Export_StepInfo) > 0)
                {
                    WriteStepInfoPage(package, adapter);
                    exportInfo.finishRows += 1;
                    WriteStepDataPage(package, adapter);
                    exportInfo.finishRows += 1;
                }
                package.Save();
            }

            exportInfo.EndTime = DateTime.Now;
            TimeSpan spead = exportInfo.EndTime.Subtract(exportInfo.BeginTime);
            MsgUtil.WriteLog(string.Format("文件导出消耗{0}s", spead.TotalSeconds));

            return 0;
        }

        static void WriteLayerCyclePage(ExcelPackage package, BdfAdapter adapter, ref FileExportInfo exportInfo)
        {
            ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("CycleLayer");
            int column = 1;
            int row = 1;
            foreach (var item in BdfDataTransfer.CycleLayerTitles)
            {
                worksheet.Cells[row, column++].Value = item;
                worksheet.Column(column - 1).AutoFit();
            }

            SetHeadSytle(worksheet, BdfDataTransfer.CycleLayerTitles.Length);
            List <CycleStatisticsNode> cycles = adapter.GetCycles();
            foreach (CycleStatisticsNode item in cycles)
            {
                if (exportInfo.Request.beginCycle > 0 && (item.dwCycleIndex + 1 < exportInfo.Request.beginCycle ||
                    item.dwCycleIndex + 1 > exportInfo.Request.endCycle))
                    continue;   //指定循环区间外的

                List<string> rowData = BdfDataTransfer.FormatCycleLayer(item);
                row++;
                column = 1;
                foreach (var itemCell in rowData)
                {
                    worksheet.Cells[row, column++].Value = itemCell;
                }
            }

            exportInfo.finishRows += row - 1;
        }
        static int WriteLayerStepPage(ExcelPackage package, BdfAdapter adapter, ref FileExportInfo exportInfo)
        {
            ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("StepLayer");
            int column = 1;
            int row = 1;
            worksheet.Cells[row, column++].Value = BdfDataTransfer.CycleLayerTitles[0];     //增加循环号
            worksheet.Column(column - 1).AutoFit();
            foreach (var item in BdfDataTransfer.StepLayerTitles)
            {
                worksheet.Cells[row, column++].Value = item;
                worksheet.Column(column - 1).AutoFit();
            }

            SetHeadSytle(worksheet, BdfDataTransfer.StepLayerTitles.Length + 1);

            List<CycleStatisticsNode> cycles = adapter.GetCycles();
            foreach (CycleStatisticsNode item in cycles)
            {
                if (exportInfo.Request.beginCycle > 0 && (item.dwCycleIndex + 1 < exportInfo.Request.beginCycle ||
                    item.dwCycleIndex + 1 > exportInfo.Request.endCycle))
                    continue;   //指定循环区间外的

                for (int i = (int)item.dwStartStepIndex; i <= item.dwEndStepIndex; i++)
                {
                    StepStatisticsNode stepNode = adapter.GetStepNode(i);
                    List<string> rowData = BdfDataTransfer.FormatStepLayer(stepNode);
                    rowData.Insert(0, (item.dwCycleIndex + 1).ToString());

                    row++;
                    column = 1;
                    foreach (var itemCell in rowData)
                    {
                        worksheet.Cells[row, column++].Value = itemCell;
                    }
                }
            }

            exportInfo.finishRows += row - 1;
            return row - 1;
        }

        static int WriteLogPage(ExcelPackage package, BdfAdapter adapter)
        {
            long nRows = 0;
            ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("Log");
            int column = 1;
            int row = 1;
            foreach (var item in BdfDataTransfer.LogTitles)
            {
                worksheet.Cells[row, column++].Value = item;
                //worksheet.Column(column - 1).AutoFit();
            }

            SetHeadSytle(worksheet, BdfDataTransfer.LogTitles.Length);
            List<SingleHisLogData> logs = adapter.GetLogs();
            foreach (var item in logs)
            {
                List<string> logRecord = BdfDataTransfer.FormatLog(item);
                column = 1;
                row++;
                foreach (var itemC in logRecord)
                {
                    worksheet.Cells[row, column++].Value = itemC;
                }
            }

            SetColumnAutoFit(worksheet, BdfDataTransfer.LogTitles.Length);
            return row - 1;
        }

        static void SetHeadSytle(ExcelWorksheet worksheet, int columns)     //设置第一行列标题样式及冻结
        {
            using (ExcelRange r = worksheet.Cells[1, 1, 1, columns])
            {
                r.Style.Font.Color.SetColor(System.Drawing.Color.White);
                r.Style.Font.Bold = true;
                r.Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
                r.Style.Fill.BackgroundColor.SetColor(System.Drawing.ColorTranslator.FromHtml("#1fb5ad"));
            }
            worksheet.View.FreezePanes(2, 1);
        }

        static void SetColumnAutoFit(ExcelWorksheet worksheet, int columns)  //设置列宽自适应
        {
            for (int column = 1;column <= columns; ++column)
            {
                worksheet.Column(column).AutoFit();   //填充数据后设置自适应，耗时稍长
            }
        }
        static int WriteNoramlPage(ExcelPackage package, BdfAdapter adapter, ref FileExportInfo exportInfo, CancellationToken token)
        {
            ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("CycleLayer");
            int column = 1;
            int row = 1;
            foreach (var item in BdfDataTransfer.CycleLayerTitles)
            {
                worksheet.Cells[row, column++].Value = item;
                worksheet.Column(column - 1).AutoFit();
            }

            column = 2;
            row++;
            foreach (var item in BdfDataTransfer.StepLayerTitles)
            {
                worksheet.Cells[row, column++].Value = item;
            }

            column = 3;
            row++;
            foreach (var item in BdfDataTransfer.RecordLayerTitles)
            {
                worksheet.Cells[row, column++].Value = item;
            }

            int columnCount = Math.Max(1 + BdfDataTransfer.StepLayerTitles.Length, 2 + BdfDataTransfer.RecordLayerTitles.Length);
            //SetHeadSytle(worksheet, columnCount);
            SetColumnAutoFit(worksheet, columnCount);
            worksheet.View.FreezePanes(4, 4);
            List<CycleStatisticsNode> cycles = adapter.GetCycles();
            foreach (CycleStatisticsNode item in cycles)
            {
                if (exportInfo.Request.beginCycle > 0 && (item.dwCycleIndex + 1 < exportInfo.Request.beginCycle ||
                    item.dwCycleIndex + 1 > exportInfo.Request.endCycle))
                    continue;   //指定循环区间外的

                List<string> rowData = BdfDataTransfer.FormatCycleLayer(item);
                row++;
                column = 1;
                foreach (var itemCell in rowData)
                {
                    worksheet.Cells[row, column++].Value = itemCell;
                }

                for (int i = (int)item.dwStartStepIndex; i <= item.dwEndStepIndex; i++)
                {
                    StepStatisticsNode stepNode = adapter.GetStepNode(i);
                    List<string> rowStepData = BdfDataTransfer.FormatStepLayer(stepNode);

                    row++;
                    column = 2;
                    foreach (var itemCell in rowStepData)
                    {
                        worksheet.Cells[row, column++].Value = itemCell;
                    }

                    for (UInt32 r = stepNode.dwFirstRecordIndex; r <= stepNode.dwLastRecordIndex; r++)
                    {
                        BdfRecord pRecord = adapter.GetCurRecord(r);
                        List<string> rowRecordData = BdfDataTransfer.FormatRecordLayer(pRecord);

                        row++;
                        column = 3;
                        foreach (var itemCell in rowRecordData)
                        {
                            worksheet.Cells[row, column++].Value = itemCell;
                        }

                        if (row % 500 == 0 && token.IsCancellationRequested)
                            return -1;
                        else if (row % 500 == 0)
                            exportInfo.finishRows += 500;

                    }
                }
            }

            exportInfo.finishRows += row % 500 - 2;
            return row - 3;
        }
        static int WriteLayerRecordPage(ExcelPackage package, BdfAdapter adapter, ref FileExportInfo exportInfo, CancellationToken token)
        {
            ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("RecordLayer");
            int column = 1;
            int row = 1;

            List<string> recordHead = BdfDataTransfer.RecordLayerTitles.ToList();
            recordHead.Insert(2, BdfDataTransfer.CycleLayerTitles[0]);      //增加循环号
            recordHead.Insert(3, BdfDataTransfer.StepLayerTitles[0]);       //增加工步序号
            foreach (var item in recordHead)
            {
                worksheet.Cells[row, column++].Value = item;
                //if (item == "绝对时间")
                //    worksheet.Column(column - 1).
                //worksheet.Column(column - 1).AutoFit();
            }

            //设置第一行列标题样式
            SetHeadSytle(worksheet, recordHead.Count);

            List<CycleStatisticsNode> cycles = adapter.GetCycles();
            foreach (CycleStatisticsNode item in cycles)
            {
                if (exportInfo.Request.beginCycle > 0 && (item.dwCycleIndex + 1 < exportInfo.Request.beginCycle ||
                    item.dwCycleIndex + 1 > exportInfo.Request.endCycle))
                    continue;   //指定循环区间外的

                for (int i = (int)item.dwStartStepIndex; i <= item.dwEndStepIndex; i++)
                {
                    StepStatisticsNode stepNode = adapter.GetStepNode(i);
                    for (UInt32 r = stepNode.dwFirstRecordIndex; r <= stepNode.dwLastRecordIndex; r++)
                    {
                        BdfRecord pRecord = adapter.GetCurRecord(r);
                        List<string> rowData = BdfDataTransfer.FormatRecordLayer(pRecord);

                        rowData.Insert(2, (item.dwCycleIndex + 1).ToString());
                        rowData.Insert(3, (i + 1).ToString());

                        row++;
                        column = 1;
                        foreach (var itemCell in rowData)
                        {
                            worksheet.Cells[row, column++].Value = itemCell;
                        }

                        if (row % 500 == 0 && token.IsCancellationRequested)
                            return -1;
                        else if (row % 500 == 0)
                            exportInfo.finishRows += 500;

                    }
                }
            }

            SetColumnAutoFit(worksheet, recordHead.Count);
            exportInfo.finishRows += row % 500;
            return row - 1;
        }

        static void WriteStepInfoPage(ExcelPackage package, BdfAdapter adapter)
        {
            ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("StepInfo");
            int column = 1;
            int row = 1;
            ChannelDeviceInfo devInfo = adapter.GetChlInfo();
            worksheet.Cells[row, column++].Value = "通道";    //row1
            worksheet.Cells[row, column++].Value = devInfo.devId.ToString()+"-"+ devInfo.chlId.ToString();
            worksheet.Cells[row, column++].Value = "并联";
            worksheet.Cells[row, column++].Value = devInfo.pallelCount.ToString();
            worksheet.Cells[row, column++].Value = "下位机版本";
            worksheet.Cells[row, column++].Value = devInfo.xwjVer;

            BmsStepFileInfo stepInfo = adapter.GetStepInfo();
            column = 1;
            worksheet.Cells[++row, column++].Value = "电压下限";        //row2
            worksheet.Cells[row, column++].Value = stepInfo.lowVol.ToString("F3") + "V";
            worksheet.Cells[row, column++].Value = "电流下限";
            worksheet.Cells[row, column++].Value = stepInfo.lowCurrent.ToString("F3") + "A";
            worksheet.Cells[row, column++].Value = "中位机版本";
            worksheet.Cells[row, column++].Value = devInfo.midVer;

            column = 1;
            worksheet.Cells[++row, column++].Value = "电压上限";        //row3
            worksheet.Cells[row, column++].Value = stepInfo.highVol.ToString("F3") + "V";
            worksheet.Cells[row, column++].Value = "电流上限";
            worksheet.Cells[row, column++].Value = stepInfo.highCurrent.ToString("F3") + "A";
            worksheet.Cells[row, column++].Value = "条码";
            worksheet.Cells[row, column++].Value = devInfo.barcode;

            column = 1;
            worksheet.Cells[++row, column++].Value = "功率下限";        //row4
            worksheet.Cells[row, column++].Value = stepInfo.lowPower.ToString("F3") + "W";
            worksheet.Cells[row, column++].Value = "容量下限";
            if ((stepInfo.uProtectState & (long)ProtectState.ePos_lowCap) > 0)
                worksheet.Cells[row, column++].Value = stepInfo.lowCap.ToString("F3") + "Ah";
            else
                column++;
            worksheet.Cells[row, column++].Value = "时间间隔";
            if ((stepInfo.uRecordState & (long)RecordState.ePos_timeInterval) > 0)
                worksheet.Cells[row, column++].Value = (stepInfo.timeInterval*0.001).ToString("F2") + "S";

            column = 1;
            worksheet.Cells[++row, column++].Value = "功率上限";        //row5
            worksheet.Cells[row, column++].Value = stepInfo.highPower.ToString("F3") + "W";
            worksheet.Cells[row, column++].Value = "容量上限";
            if ((stepInfo.uProtectState & (long)ProtectState.ePos_highCap) > 0)
                worksheet.Cells[row, column++].Value = stepInfo.highCap.ToString("F3") + "Ah";
            else
                column++;
            worksheet.Cells[row, column++].Value = "电压间隔";
            if ((stepInfo.uRecordState & (long)RecordState.ePos_volInterval) > 0)
                worksheet.Cells[row, column++].Value = (stepInfo.volInterval * DaFileElement.SCALE_IU).ToString("F3") + "V";

            column = 1;
            worksheet.Cells[++row, column++].Value = "温度下限";        //row6
            if ((stepInfo.uProtectState & (long)ProtectState.ePos_highTempl) > 0)
                worksheet.Cells[row, column++].Value = stepInfo.lowTemp.ToString("F1") + "℃";
            else
                column++;
            worksheet.Cells[row, column++].Value = "中位机IP";
            worksheet.Cells[row, column++].Value = devInfo.midIp;
            //if ((stepInfo.uProtectState & (long)ProtectState.ePos_lowCap) > 0)
            //    worksheet.Cells[row, column++].Value = stepInfo.highCap.ToString("F3") + "Ah";
            //else
            //    column++;
            worksheet.Cells[row, column++].Value = "电流间隔";
            if ((stepInfo.uRecordState & (long)RecordState.ePos_curInterval) > 0)
                worksheet.Cells[row, column++].Value = (stepInfo.volInterval * DaFileElement.SCALE_IU).ToString("F3") + "A";

            column = 1;
            worksheet.Cells[++row, column++].Value = "温度上限";        //row7
            if ((stepInfo.uProtectState & (long)ProtectState.ePos_lowTempl) > 0)
                worksheet.Cells[row, column++].Value = stepInfo.highTemp.ToString("F1") + "℃";
            else
                column++;
            //worksheet.Cells[row, column++].Value = "";
            //if ((stepInfo.uProtectState & (long)ProtectState.ePos_lowCap) > 0)
            //    worksheet.Cells[row, column++].Value = stepInfo.highCap.ToString("F3") + "Ah";
            //else
            //    column++;
            //worksheet.Cells[row, column++].Value = "";
            //if ((stepInfo.uRecordState & (long)RecordState.ePos_curInterval) > 0)
            //    worksheet.Cells[row, column++].Value = (stepInfo.volInterval * DaFileElement.SCALE_IU).ToString("F3") + "A";

            SetColumnAutoFit(worksheet, 6);
        }

        static void WriteStepDataPage(ExcelPackage package, BdfAdapter adapter)
        {
            ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("StepData");
            int column = 1;
            int row = 1;
            if (DaFileElement.MAGIC_NUM_STEP_FILE == adapter.StepFileType)  //高级工步
            {
                foreach (var item in BdfDataTransfer.AdvStepTitles)
                {
                    worksheet.Cells[row, column++].Value = item;
                }

                List<SingleStepInfo>  steps = adapter.GetStepData();
                
                foreach (var item in steps)
                {
                    column = 1;
                    worksheet.Cells[++row, column++].Value = item.StepNo.ToString() ;
                    worksheet.Cells[row, column++].Value = BdfDataTransfer.GetStepTypeName(item.StepName);
                    if (item.StepName == (byte)StepType.STEP_MODE_FINISH)
                        break;
                    else if (item.StepName == (byte)StepType.STEP_MODE_RECYCLE)
                    {
                        worksheet.Cells[row, column++].Value = "起始 " + ((int)item.StepParams[0]);
                        //worksheet.Cells[row, column++].Value = ((int)item.StepParams[0]).ToString();
                        worksheet.Cells[row, column++].Value = "次数 "+ (int)item.StepParams[1];
                        //worksheet.Cells[row, column++].Value = ((int)item.StepParams[1]).ToString();
                    }
                    else
                    {
                        int nRefRow = WriteAdvStepParam(row, worksheet, item);

                        int nRefRow2 = WriteAdvStepCond(row, worksheet, item);
                        int nRecord = 0;
                        foreach (var itemRecord in item.RecordConditions)
                        {
                            worksheet.Cells[row + nRecord, 10].Value = BdfDataTransfer.GetRecordName(itemRecord.RecordConditionType);
                            worksheet.Cells[row+ nRecord++, 11].Value = itemRecord.RecordConditionParam.ToString()+"ms";
                        }

                        if (item.ExpandParamCount > 0)
                        {
                            if (item.ExpandParams[0].ExpandParamType == 1)
                                worksheet.Cells[row, 12].Value = item.ExpandParams[0].ExpandParamParamValues[0].ToString() + "ms";
                        }

                        row += Math.Max(Math.Max(nRefRow, nRefRow2), nRecord - 1);
                    }
                }
                SetColumnAutoFit(worksheet, BdfDataTransfer.AdvStepTitles.Length);
            }
            else if (DaFileElement.MAGIC_NUM_STEP_FILE_STD == adapter.StepFileType)     //标准工步
            {
                foreach (var item in BdfDataTransfer.StdStepTitles)
                {
                    worksheet.Cells[row, column++].Value = item;
                }

                List<SingleStepInfo> steps = adapter.GetStepData();

                foreach (var item in steps)
                {
                    column = 1;
                    worksheet.Cells[++row, column++].Value = item.StepNo.ToString();
                    worksheet.Cells[row, column++].Value = BdfDataTransfer.GetStepTypeName(item.StepName);
                    if (item.StepName == (byte)StepType.STEP_MODE_FINISH)
                        break;
                    else if (item.StepName == (byte)StepType.STEP_MODE_RECYCLE)
                    {
                        worksheet.Cells[row, column++].Value = "起始 "+ ((int)item.StepParams[0]).ToString();
                        //worksheet.Cells[row, column++].Value = ((int)item.StepParams[0]).ToString();
                        worksheet.Cells[row, column++].Value = "次数 " + ((int)item.StepParams[1]).ToString();
                        //worksheet.Cells[row, column++].Value = ((int)item.StepParams[1]).ToString();
                    }
                    else
                    {
                        if (StepType.STEP_MODE_I_UNCHARGE == (StepType)item.StepName || StepType.STEP_MODE_I_CHARGE == (StepType)item.StepName)
                            worksheet.Cells[row , 4].Value = item.StepParams[0].ToString();
                        else if (StepType.STEP_MODE_U_CHARGE == (StepType)item.StepName || StepType.STEP_MODE_U_UNCHARGE == (StepType)item.StepName)
                            worksheet.Cells[row, 3].Value = item.StepParams[0].ToString() ;
                        else if (StepType.STEP_MODE_IU_UNCHARGE == (StepType)item.StepName || StepType.STEP_MODE_IU_CHARGE == (StepType)item.StepName)
                        {
                            worksheet.Cells[row, 3].Value = item.StepParams[1].ToString();
                            worksheet.Cells[row, 4].Value = item.StepParams[0].ToString();
                        }
                        else if (StepType.STEP_MODE_POWER_UNCHARGE == (StepType)item.StepName|| StepType.STEP_MODE_IU_CHARGE == (StepType)item.StepName)
                            worksheet.Cells[row, 9].Value = item.StepParams[0].ToString() ;

                        foreach (var itemCond in item.CutOffConditions)
                        {
                            if (COND_PARA.COND_PARA_TIME == (COND_PARA)itemCond.CutOffConditionType)
                                worksheet.Cells[row, 5].Value = BdfDataTransfer.FromatTimeSpan((UInt64)itemCond.CutOffConditionParam);
                            else if (COND_PARA.COND_PARA_CUR == (COND_PARA)itemCond.CutOffConditionType)
                                worksheet.Cells[row, 6].Value = itemCond.CutOffConditionParamCondition.ToString();
                            else if (COND_PARA.COND_PARA_VOL == (COND_PARA)itemCond.CutOffConditionType)
                                worksheet.Cells[row , 7].Value = itemCond.CutOffConditionParamCondition.ToString();
                            else if (COND_PARA.COND_PARA_CAP == (COND_PARA)itemCond.CutOffConditionType)
                                worksheet.Cells[row , 8].Value = itemCond.CutOffConditionParamCondition.ToString();
                        }

                        if (item.ExpandParamCount > 0)
                        {
                            if (item.ExpandParams[0].ExpandParamType == 1)
                                worksheet.Cells[row , 10].Value = item.ExpandParams[0].ExpandParamParamValues[0].ToString();
                        }
                    }
                }
                SetColumnAutoFit(worksheet, BdfDataTransfer.StdStepTitles.Length);
            }
        }

        static int WriteAdvStepParam(int row, ExcelWorksheet worksheet, SingleStepInfo stepItem)
        {
            int nRefRow = 0;
            string strTmp;
            switch ((StepType)stepItem.StepName)
            {
                case StepType.STEP_MODE_I_UNCHARGE:
                case StepType.STEP_MODE_I_CHARGE://
                    {
                        worksheet.Cells[row, 3].Value = "电流";
                        worksheet.Cells[row, 4].Value = stepItem.StepParams[0].ToString() + "A";
                    }
                    break;
                case StepType.STEP_MODE_U_CHARGE://   //  恒压充电  
                case StepType.STEP_MODE_U_UNCHARGE:
                    {
                        worksheet.Cells[row, 3].Value = "电压";
                        worksheet.Cells[row, 4].Value = stepItem.StepParams[0].ToString() + "V";
                    }
                    break;
                case StepType.STEP_MODE_IU_UNCHARGE://
                case StepType.STEP_MODE_IU_CHARGE:                   //  恒流恒压充电 
                    {
                        nRefRow = 1;
                        worksheet.Cells[row, 3].Value = "电流";
                        worksheet.Cells[row, 4].Value = stepItem.StepParams[0].ToString()+"A";
                        worksheet.Cells[row + 1, 3].Value = "电压";
                        worksheet.Cells[row + 1, 4].Value = stepItem.StepParams[1].ToString()+"V";
                    }
                    break;
                case StepType.STEP_MODE_POWER_UNCHARGE:////  恒功率放电
                case StepType.STEP_MODE_POWER_CHARGE:
                    {
                        worksheet.Cells[row, 3].Value = "功率";
                        worksheet.Cells[row, 4].Value = stepItem.StepParams[0].ToString();
                    }
                    break;
                case StepType.STEP_MODE_IR_CHARGE:
                    {
                        worksheet.Cells[row, 3].Value = "阻值";
                        worksheet.Cells[row, 4].Value = stepItem.StepParams[0].ToString();
                    }
                    break;
                case StepType.STEP_MODE_Li_CHARGE:
                    {
                        nRefRow = 6;
                        worksheet.Cells[row, 3].Value = "循环次数";
                        worksheet.Cells[row, 4].Value = ((int)stepItem.StepParams[0]).ToString();
                        worksheet.Cells[row+ 1, 3].Value = "电流1";
                        worksheet.Cells[row+ 1, 4].Value = stepItem.StepParams[1].ToString() + "A";
                        worksheet.Cells[row + 2, 3].Value = "时间1";
                        worksheet.Cells[row + 2, 4].Value = ((int)stepItem.StepParams[2]).ToString() + "ms";
                        worksheet.Cells[row + 3, 3].Value = "记录时间1";
                        worksheet.Cells[row + 3, 4].Value = ((int)stepItem.StepParams[3]).ToString() + "ms";
                        worksheet.Cells[row + 4, 3].Value = "电流2";
                        worksheet.Cells[row + 4, 4].Value = stepItem.StepParams[4].ToString() + "A";
                        worksheet.Cells[row + 5, 3].Value = "时间2";
                        worksheet.Cells[row + 5, 4].Value = ((int)stepItem.StepParams[5]).ToString() + "ms";
                        worksheet.Cells[row + 6, 3].Value = "记录时间2";
                        worksheet.Cells[row + 6, 4].Value = ((int)stepItem.StepParams[6]).ToString() + "ms";
                    }
                    break;
            }

            return nRefRow;
        }

        static int WriteAdvStepCond(int row, ExcelWorksheet worksheet, SingleStepInfo stepItem)
        {
            foreach (var item in stepItem.CutOffConditions)
            {
                worksheet.Cells[row, 5].Value = BdfDataTransfer.GetCondName(item.CutOffConditionType);
                worksheet.Cells[row, 6].Value = BdfDataTransfer.GetStepCondOper(item.CutOffConditionParamCondition);
                worksheet.Cells[row, 8].Value = BdfDataTransfer.GetStepCondRelation(item.CutOffConditionRaletion);
                worksheet.Cells[row, 9].Value = BdfDataTransfer.GetStepCondAction(item.CutOffConditionProcessingType);
                string str = "";
                switch ((COND_PARA)item.CutOffConditionType)
                {
                    case COND_PARA.COND_PARA_TIME:
                        str = BdfDataTransfer.FromatTimeSpan((UInt64)item.CutOffConditionParam);
                        break;
                    case COND_PARA.COND_PARA_VOL:
                    case COND_PARA.COND_SINGLE_VOL:
                    case COND_PARA.COND_SINGLE_MAXVOL:
                    case COND_PARA.COND_SINGLE_MINVOL:
                    case COND_PARA.COND_SINGLE_ERRVOL:
                        str = item.CutOffConditionParam.ToString() + "V";
                        break;
                    case COND_PARA.COND_PARA_CUR:
                        str = item.CutOffConditionParam.ToString() + "A";
                        break;
                    case COND_PARA.COND_PARA_CAP:
                    case COND_PARA.COND_PARA_CHG_CAP:
                    case COND_PARA.COND_PARA_DISCHG_CAP:
                        str = item.CutOffConditionParam.ToString() + "Ah";
                        break;
                    case COND_PARA.COND_PARA_NRG:
                    case COND_PARA.COND_PARA_CHG_NRG:
                    case COND_PARA.COND_PARA_DISCHG_NRG:
                        str = item.CutOffConditionParam.ToString() + "Wh";
                        break;
                    case COND_PARA.COND_PARA_TEMP:
                    case COND_PARA.COND_SINGLE_MAXTEMP:
                    case COND_PARA.COND_SINGLE_MINTEMP:
                    case COND_PARA.COND_SINGLE_ERRTEMP:
                        str = item.CutOffConditionParam.ToString() + "℃";
                        break;
                }

                worksheet.Cells[row++, 7].Value = str;
            }

            return stepItem.CutOffConditionCount - 1;
        }

        //循环数+记录数+工步数+日志数+1工步信息+1工步数+1图形
        private static long CalcProgressInfo(ref FileExportInfo exportInfo, BdfAdapter adapter)
        {
            long nRows = 0;
            List<CycleStatisticsNode> cycles = adapter.GetCycles();
            foreach (CycleStatisticsNode item in cycles)
            {
                if (exportInfo.Request.beginCycle > 0 && (item.dwCycleIndex + 1 < exportInfo.Request.beginCycle||
                    item.dwCycleIndex + 1 > exportInfo.Request.endCycle))
                    continue;   //指定循环区间外的

                if ((exportInfo.Request.exportOption & (int)ExportElment.Export_CycleLayer) > 0)
                    nRows += 1;
                if ((exportInfo.Request.exportOption & (int)ExportElment.Export_StepLayer) > 0)
                    nRows += item.vecSteps.Count;

                foreach (var itemS in item.vecSteps)
                {
                    if ((exportInfo.Request.exportOption & (int)ExportElment.Export_RecordLayer) > 0)
                        nRows += itemS.nRecordTotalNum;
                }

                //nRows += item.vecSteps.Count + 1;
            }

            if ((exportInfo.Request.exportOption & (int)ExportElment.Export_Log) > 0)
                nRows += adapter.GetLogs().Count;

            if ((exportInfo.Request.exportOption & (int)ExportElment.Export_StepInfo) > 0)
                nRows += 2;

            if ((exportInfo.Request.exportOption & (int)ExportElment.Export_Graph) > 0)
                nRows += 1;

            exportInfo.totalRows = nRows;
            ExportElment fullOption = (ExportElment.Export_Graph | ExportElment.Export_StepInfo | ExportElment.Export_Log | ExportElment.Export_RecordLayer | ExportElment.Export_StepLayer | ExportElment.Export_CycleLayer);
            MsgUtil.WriteLog(string.Format("fullOption{0}", fullOption));
            return nRows;
        }
    }
}
